package cn.tedu.csmall.product.service.impl;

import cn.tedu.csmall.product.ex.ServiceException;
import cn.tedu.csmall.product.mapper.*;
import cn.tedu.csmall.product.pojo.dto.CategoryAddNewDTO;
import cn.tedu.csmall.product.pojo.dto.CategoryUpdateDTO;
import cn.tedu.csmall.product.pojo.entity.Brand;
import cn.tedu.csmall.product.pojo.entity.Category;
import cn.tedu.csmall.product.pojo.vo.BrandStandardVO;
import cn.tedu.csmall.product.pojo.vo.CategoryListItemVO;
import cn.tedu.csmall.product.pojo.vo.CategoryStandardVO;
import cn.tedu.csmall.product.service.ICategoryService;
import cn.tedu.csmall.product.web.ServiceCode;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 处理分类数据业务的实现类
 * @author 何惠民
 * @version 0.0.1
 */
@Slf4j
@Service
public class CategoryServiceImpl implements ICategoryService {

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private BrandCategoryMapper brandCategoryMapper;

    @Autowired
    private CategoryAttributeTemplateMapper categoryAttributeTemplateMapper;

    @Autowired
    private SpuMapper spuMapper;

    public CategoryServiceImpl() {
        log.debug("创建业务对象:BrandServiceImpl");
    }

    @Override
    //SpringMVC的事务 JDBC要么都成功要么都不成功
    public void addNew(CategoryAddNewDTO categoryAddNewDTO) {
        log.debug("开始处理[添加分类]的业务,参数:{}",categoryAddNewDTO);

        //查询父级类别
        Integer depth = 1;
        Long parentId = categoryAddNewDTO.getParentId();
        CategoryStandardVO parentCategory = null;
        if (parentId != 0){
            //确定当前类别的的depth值,为父级depth +1
            parentCategory = categoryMapper.getStandardById(parentId);
            log.debug(parentCategory.toString());
            if (parentCategory == null) {
                String message = "添加类别失败,所选的父级类别不存在";
                log.debug(message);
                throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
            }
            depth = parentCategory.getDepth() + 1;
        }
        log.debug("当前添加的类型的depth值为:{}",depth);

        //从参数对象中分类名称
        String categoryName = categoryAddNewDTO.getName();
        //检查分类名称是否已经被占用
        log.debug("检查分类名称是否被占用");
        int count = categoryMapper.countByName(categoryName);
        if (count > 0){
            //是:分类名称被占用,添加分类失败,抛出异常
            String message = "添加失败,分类名称被占用";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
        //否:分类名称没有被占用,则向分类表中插入数据
        log.debug("分类名称没有被占用,则向分类表中插入数据");


        //创建Category实体类的对象
        Category category = new Category();
        BeanUtils.copyProperties(categoryAddNewDTO, category);
        //补全Category对象的值 depth
        category.setDepth(depth);
        //补全Category对象的值 isParent  新增的固定为0
        category.setIsParent(0);
        log.debug("即将插入分类数据:{}", category);
        int rows = categoryMapper.insert(category);
        if (rows != 1){
            String message = "添加类别失败,服务器忙,请稍后再尝试!";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_INSERT,message);
        }

        // 检查当前新增类型的父级类别,如果父类别的isParent为0,则将父类的isParent设置为1
        if (parentId != 0){
            if (parentCategory.getIsParent() == 0){
                Category updateParentCategory = new Category();
                updateParentCategory.setId(parentId);
                updateParentCategory.setIsParent(1);
                rows = categoryMapper.update(updateParentCategory);
                if (rows != 1) {
                    String message = "删除类别失败，服务器忙，请稍后再尝试！";
                    log.debug(message);
                    throw new ServiceException(ServiceCode.ERR_UPDATE, message);
                }
            }
        }

    }


    @Override
    public void deleteById(Long id) {

        log.debug("开始处理[删除分类]的业务,参数:{}",id);
        //查询要删除的相册是否存在
        CategoryStandardVO queryResult = categoryMapper.getStandardById(id);
        //是否为null
        if (queryResult == null){
            String message = "删除分类失败,尝试删除的数据不存在";
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }

        // 检查当前尝试删除的类别是否存在子级类别：判断以上查询结果的isParent是否为1
        if (queryResult.getIsParent() == 1) {
            // 是：当前尝试删除的类别“是父级类别”（包含子级），抛出异常（ERR_CONFLICT）
            String message = "删除类别失败，尝试删除的类别仍包含子级类别！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        // 如果此类别关联了品牌，则不允许删除
        int count = brandCategoryMapper.countByCategory(id);
        if (count > 0) {
            String message = "删除类别失败，当前类别仍关联了类别！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_DELETE, message);
        }

        // 如果此类别关联了属性模板，则不允许删除
        count = categoryAttributeTemplateMapper.countByCategory(id);
        if (count > 0) {
            String message = "删除类别失败，当前类别仍关联了属性模板！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_DELETE, message);
        }

        // 如果此类别关联了SPU，则不允许删除
        count = spuMapper.countByCategory(id);
        if (count > 0) {
            String message = "删除类别失败，当前类别仍关联了商品！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_DELETE, message);
        }

        //调用mapper对象的deleteById()方法执行删除
        log.debug("即将执行删除,参数:{}",id);
        int rows = categoryMapper.deleteById(id);
        if (rows != 1){
            String message = "删除类别失败,服务器忙,请稍后再尝试!";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_DELETE,message);
        }

        // ====== 如果这是父级类别中的最后一个子级，则将父级的isParent改为0 =====
        // 从当前尝试删除的类别对象中取出parentId
        Long parentId = queryResult.getParentId();
        // 判断当前类别是否不为1级类别，即parentId不为0
        if (parentId != 0) {
            // 调用Mapper对象的countByParentId(parentId)进行统计
            count = categoryMapper.countByParentId(parentId);
            // 判断统计结果是否为0
            if (count == 0) {
                // 创建新的Category对象，用于更新父级，此Category对象中需要封装：id（parentId），isParent（0）
                Category parentCategory = new Category();
                parentCategory.setId(parentId);
                parentCategory.setIsParent(0);
                // 调用Mapper对象的【更新】功能，执行修改数据，并获取返回值
                rows = categoryMapper.update(parentCategory);
                // 判断返回值是否不为1
                if (rows != 1) {
                    // 是：抛出异常（ERR_UPDATE）
                    String message = "删除类别失败，服务器忙，请稍后再尝试！";
                    log.warn(message);
                    throw new ServiceException(ServiceCode.ERR_UPDATE, message);
                }
            }
        }
    }

    @Override
    public void update(CategoryUpdateDTO categoryUpdateDTO) {
        log.debug("开始处理修改分类的业务参数:{}",categoryUpdateDTO);
        String name = categoryUpdateDTO.getName();
        int rows = categoryMapper.countByName(name);
        if (rows > 0){
            CategoryStandardVO categoryStandardVO = categoryMapper.getStandardById(categoryUpdateDTO.getId());
            if (!categoryStandardVO.getName().equals(categoryUpdateDTO.getName())){
                String message = "修改失败,修改后的名称已经存在,请更换";
                log.debug(message);
                throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
            }
        }
        Category category = new Category();
        BeanUtils.copyProperties(categoryUpdateDTO, category);
        rows = categoryMapper.update(category);
        if (rows != 1){
            String message = "修改分类失败,服务器忙,请稍后再尝试!";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_INSERT,message);
        }
    }

    @Override
    public void setEnable(Long id) {
        updateEnableById(id,1);
    }

    @Override
    public void setDisable(Long id) {
        updateEnableById(id,0);
    }

    private void updateEnableById(Long id, Integer enable){
        log.debug("开始处理[更新分类是否启用]的业务,参数:{}",id);
        //id值为1的分类不允许删除 root
        if (id.equals(1)){
            String[] s = {"禁用","启用"};
            String message = s[enable] + "分类失败,尝试修改的数据不存在";
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        // 查询要删除的分类是否存在
        CategoryStandardVO queryResult = categoryMapper.getStandardById(id);
        //是否为null
        if (queryResult == null){
            String[] s = {"禁用","启用"};
            String message = s[enable] + "分类失败,尝试修改的数据不存在";
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        //判断enable和参数enable1是否相同
        if (queryResult.getEnable().equals(enable)){
            String[] s = {"禁用","启用"};
            String message = s[enable] + "分类失败,改分类已经" + s[enable];
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
        Category category = new Category();
        category.setId(id);
        category.setEnable(enable);
        int rows = categoryMapper.update(category);
        if (rows != 1){
            String[] s = {"禁用","启用"};
            String message = s[enable] + "分类失败,尝试修改的数据不存在";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE,message);
        }
    }


    @Override
    public void setDisplay(Long id) {
        log.debug("开始处理【显示类别】的业务，参数：{}", id);
        // 调用Mapper对象的getDetailsById()方法执行查询
        CategoryStandardVO queryResult = categoryMapper.getStandardById(id);
        // 判断查询结果是否为null
        if (queryResult == null) {
            // 是：此id对应的数据不存在，则抛出异常(ERR_NOT_FOUND)
            String message = "显示类别失败，尝试访问的数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 判断查询结果中的isDisplay是否为1
        if (queryResult.getIsDisplay() == 1) {
            // 是：此id对应的类别已经是显示状态，则抛出异常(ERR_CONFLICT)
            String message = "显示类别失败，当前类别已经处于显示状态！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        // 创建Category对象（作为修改数据的方法的参数）
        Category category = new Category();
        // 向Category对象中封装id（参数id）与enable（固定为1）属性的值
        category.setId(id);
        category.setIsDisplay(1);
        // 调用Mapper对象的update()修改类别数据，并获取返回值
        int rows = categoryMapper.update(category);
        // 判断以上返回值是否不为1
        if (rows != 1) {
            // 是：抛出异常(ERR_UPDATE)
            String message = "显示类别失败，服务器忙，请稍后再次尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }



    @Override
    public void setHidden(Long id) {
        log.debug("开始处理【隐藏类别】的业务，参数：{}", id);
        // 调用Mapper对象的getDetailsById()方法执行查询
        CategoryStandardVO queryResult = categoryMapper.getStandardById(id);
        // 判断查询结果是否为null
        if (queryResult == null) {
            // 是：此id对应的数据不存在，则抛出异常(ERR_NOT_FOUND)
            String message = "隐藏类别失败，尝试访问的数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 判断查询结果中的isDisplay是否为0
        if (queryResult.getIsDisplay() == 0) {
            // 是：此id对应的类别已经是隐藏状态，则抛出异常(ERR_CONFLICT)
            String message = "隐藏类别失败，当前类别已经处于隐藏状态！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }
        // 创建Category对象（作为修改数据的方法的参数）
        Category category = new Category();
        // 向Category对象中封装id（参数id）与enable（固定为1）属性的值
        category.setId(id);
        category.setIsDisplay(0);
        // 调用Mapper对象的update()修改类别数据，并获取返回值
        int rows = categoryMapper.update(category);
        // 判断以上返回值是否不为1
        if (rows != 1) {
            // 是：抛出异常(ERR_UPDATE)
            String message = "隐藏类别失败，服务器忙，请稍后再次尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }

    @Override
    public CategoryStandardVO getStandardById(Long id) {
        log.debug("开始处理[查询分类详情]的业务,参数:{}",id);
        CategoryStandardVO categoryStandardVO = categoryMapper.getStandardById(id);
        if (categoryStandardVO == null){
            String message = "没有查询到id为"+id+"的分类详情数据";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        log.debug("根据id{}查询到品牌详情数据{}",id,categoryStandardVO);
        return categoryStandardVO;
    }

    @Override
    public List<CategoryListItemVO> list() {
        log.debug("开始处理[查询分类列表]的业务,无参数");
        return categoryMapper.list();
    }

    @Override
    public List<CategoryListItemVO> listByparentId(Long parentId) {
        log.debug("开始处理根据父级id查询分类参数{}",parentId);
        return categoryMapper.listByparentId(parentId);
    }

}
